package gate.server.handler;

import gate.base.cache.ClientChannelCache;
import gate.base.chachequeue.CacheQueue;
import gate.base.domain.ChannelData;
import gate.util.StringUtils;
import io.netty.channel.*;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.ReferenceCountUtil;
import test.CountHelper;

import java.net.InetSocketAddress;
import java.util.List;

/**
 * 接收终端报文处理类
 *
 * @author yangcheng
 * @Description:
 * @date: 2019年3月30日
 */
@Sharable
public class SocketInHandler extends ChannelInboundHandlerAdapter {

    /**
     * 连接
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        Channel channel = ctx.channel();
        InetSocketAddress insocket = (InetSocketAddress) channel.remoteAddress();
        String host = insocket.getHostName();
        String clientIpAddress = StringUtils.formatIpAddress(host.equals("localhost") ? "127.0.0.1" : host,
                String.valueOf(insocket.getPort()));
        Integer count = CacheQueue.ipCountRelationCache.get(clientIpAddress);
        if (count != null && count.intValue() < 10000) {
            CacheQueue.ipCountRelationCache.put(clientIpAddress, count + 1);
        } else {
            CacheQueue.ipCountRelationCache.put(clientIpAddress, 1);
        }
        ;
        ClientChannelCache.set(clientIpAddress, channel);
    }

    /**
     * 断开
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        /**
         * 下线时删除缓存中对应的client的缓存
         */
        Channel channel = ctx.channel();
        InetSocketAddress insocket = (InetSocketAddress) channel.remoteAddress();
        String host = insocket.getHostName();
        String ipAddress = StringUtils.formatIpAddress(host.equals("localhost") ? "127.0.0.1" : host,
                String.valueOf(insocket.getPort()));
        ClientChannelCache.removeOne(ipAddress);
    }

    /**
     * 读取外部数据
     *
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            if (msg instanceof List) {
                List<ChannelData> lists = (List<ChannelData>) msg;
                for (ChannelData channelData : lists) {
                    CacheQueue.up2MasterQueue.put(channelData);//数据上报
                    analyse();
                }

            } else {
                ChannelData channelData = (ChannelData) msg;
                CacheQueue.up2MasterQueue.put(channelData);
//				analyse();
            }

        } catch (Exception e) {//异常捕获
//            ctx.channel().close();
        } finally {
            ReferenceCountUtil.release(msg);//释放内存
        }


    }

    /**
     * 异常处理
     *
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // TODO Auto-generated method stub
        super.exceptionCaught(ctx, cause);
        /**
         * 发生异常时删除缓存中对应的client的缓存
         */
        Channel channel = ctx.channel();
        InetSocketAddress insocket = (InetSocketAddress) channel.remoteAddress();
        String host = insocket.getHostName();
        String ipAddress = StringUtils.formatIpAddress(host.equals("localhost") ? "127.0.0.1" : host
                , String.valueOf(insocket.getPort()));
        String clientIpAddress = ipAddress;
        ClientChannelCache.removeOne(clientIpAddress);
        cause.printStackTrace();
    }

    /**
     * 心跳检测触发的事件通过本方法捕获
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleState state = ((IdleStateEvent) evt).state();
            if (state == state.READER_IDLE) {
                ChannelFuture fcutrue = ctx.close();
                fcutrue.addListener(new ChannelFutureListener() {
                    public void operationComplete(ChannelFuture future) throws Exception {
                        Channel channel = future.channel();
                        InetSocketAddress insocket = (InetSocketAddress) channel.remoteAddress();
                        String host = insocket.getHostName();
                        String ipAddress = StringUtils.formatIpAddress(host.equals("localhost") ? "127.0.0.1" : host,
                                String.valueOf(insocket.getPort()));
                        String key = ipAddress;
                        System.out.println(key + "心跳超时下线成功....");
//						ClientChannelCache.removeOne(key);
                    }
                });
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }

    }

    /**
     * 统计每1000次并发耗时  单位ms
     */
    private void analyse() {

        if (CountHelper.startTimeLong.get() == 0) {
            synchronized (CountHelper.class) {
                if (CountHelper.startTimeLong.get() == 0) {
                    CountHelper.startTimeLong.set(System.currentTimeMillis());
                }
            }
        }
        CountHelper.clientRecieveCount.addAndGet(1);
        long curNum = CountHelper.clientRecieveCount.get();
        if (curNum % 1000 == 0) {
            System.out.println(curNum + "花费了：" + (System.currentTimeMillis() - CountHelper.startTimeLong.get()));
        }
    }


}
